/*
 * tp2855.c
 *
 *  Created on: 2024年4月11日
 *      Author: NI
 */
#include <stdio.h>
#include <errno.h>
#include <pthread.h>
#include "i2c-decoder.h"
#include "tp2855_reg.h"
#include "libdecoder_tp2855.h"

#define TP2855_DEVICE_ID_REG_H	(0xFE)
#define TP2855_DEVICE_ID_REG_L	(0xFF)
#define TP2855_DECICE_ID_H		(0x28)
#define TP2855_DECICE_ID_L		(0x55)
#define TP2855_PAGE_REG			0x40
#define TP2855_STATUS_REG		0x01
#define TP2855_CONNECT_MASK		0x80
#define TP2855_LOCK_MASK		0x60

static pthread_mutex_t mutex;

int camera_decoder_tp2855_check(){
	int ret = EOK;
	uint8_t device_id = 0;

	pthread_mutex_lock(&mutex);

	if(EOK != i2c_decoder_rd(TP2855_DEVICE_ID_REG_H, &device_id)){
		goto i2c_error;
	}

	if(device_id != TP2855_DECICE_ID_H){
		goto check_error;
	}

	if(EOK != i2c_decoder_rd(TP2855_DEVICE_ID_REG_L, &device_id)){
		goto i2c_error;
	}

	if(device_id != TP2855_DECICE_ID_L){
		goto check_error;
	}
	return ret;

i2c_error:
	pthread_mutex_unlock(&mutex);
	return EIO;
check_error:
	pthread_mutex_unlock(&mutex);
	return ENOTSUP;
}

/*#######################	export to user	#######################*/
int camera_decoder_init(tp2855_dev_t * dev){
	int ret = EOK;

	ret = pthread_mutex_init(&mutex, NULL);
	if(ret != EOK){
		printf("Try to init mutex fail\n");
		return ret;
	}

	ret = i2c_decoder_init(dev->path, dev->decoder_addr);
	if(ret != EOK){
		printf("i2c_decoder_init fail, i2c path [%s].\n", dev->path);
		return ret;
	}

	ret = camera_decoder_tp2855_check();
	if(ret != EOK){
		printf("TP2855 device id check error!\n");
	}

	return ret;
}

int camera_decoder_init_reg_map(tp2855_dev_t * dev){
	pthread_mutex_lock(&mutex);
	TP2855_decoder_init(dev->camera.channel, dev->camera.fmt, dev->camera.std);
	pthread_mutex_unlock(&mutex);
	return EOK;
}

int camera_decoder_mipi_config(tp2855_dev_t * dev){
	pthread_mutex_lock(&mutex);
	TP2855_mipi_out(dev->mipi_config);
	pthread_mutex_unlock(&mutex);
	return EOK;
}

int camera_decoder_mipi_output(uint8_t enable){
	pthread_mutex_lock(&mutex);
	if(enable){
		if(EOK != i2c_decoder_wr(TP2855_PAGE_REG, MIPI_PAGE)){
			return EIO;
		}
		if(EOK != i2c_decoder_wr(0x23, 0x00)){
			return EIO;
		}
	}else{
		if(EOK != i2c_decoder_wr(TP2855_PAGE_REG, MIPI_PAGE)){
			return EIO;
		}
		if(EOK != i2c_decoder_wr(0x23, 0x02)){
			return EIO;
		}
	}
	pthread_mutex_unlock(&mutex);
	return EOK;
}

int camera_decoder_deinit(){
	pthread_mutex_destroy(&mutex);
	i2c_decoder_deinit();
	return EOK;
}

int camera_decoder_check_connect(tp2855_dev_t * dev, uint8_t * status){
	pthread_mutex_lock(&mutex);

	if(EOK != i2c_decoder_wr(TP2855_PAGE_REG, dev->camera.channel)){
		return EIO;
	}

	if(EOK != i2c_decoder_rd(TP2855_STATUS_REG, status)){
		return EIO;
	}

	if((*status & TP2855_CONNECT_MASK) == 0){
		*status = 1;
	}else{
		*status = 0;
	}

	pthread_mutex_unlock(&mutex);
	return EOK;
}

int camera_decoder_check_lock(tp2855_dev_t * dev, uint8_t * status){
	pthread_mutex_lock(&mutex);

	if(EOK != i2c_decoder_wr(TP2855_PAGE_REG, dev->camera.channel)){
		return EIO;
	}

	if(EOK != i2c_decoder_rd(TP2855_STATUS_REG, status)){
		return EIO;
	}

	if((*status & TP2855_LOCK_MASK) != TP2855_LOCK_MASK){
		*status = 0;
	}else{
		*status = 1;
	}

	pthread_mutex_unlock(&mutex);
	return EOK;
}

int camera_decoder_dump(){
	return i2c_decoder_dump();
}

/***************************************************************************************************/
/*	init tp2855_dev
 * 	camera_decoder_init
 * 	camera_decoder_check_connect
 * 	camera_decoder_init_reg_map
 * 	camera_decoder_check_lock
 * 	camera_decoder_mipi_config
 * 	camera_decoder_mipi_output(1)
 * 	*/
